from threading import Event,Lock,Thread
from time import time

timeout = 10
cache = {}
lock = Lock()
NotReady = object()

class Trigger(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.started = False
        self.lock = Lock()
    def fire(self,val):
        self.lock.acquire()
        try:
            if self.started:
                return
            self.started = True
        finally:
            self.lock.release()
        self.val = val
        self.start()
    def run(self):
        pass

def put(key,val):
    global cache,timeout
    try:
        lock.acquire()
        now = time()
        old = now - timeout
        for k in cache.keys():
            (v,e,t) = cache[k]
            if t < old:
                del cache[k]
        if key in cache:
            (v,e,t) = cache[key]
            if e.isSet():
                if isinstance(v,Trigger):
                    v.fire(val)
                return
        else:
            e = Event()
        cache[key] = (val,e,now)
    finally:
        lock.release()
    e.set()

def get(key):
    global cache,timeout
    try:
        lock.acquire()
        if key in cache:
            (v,e,t)=cache[key]
            if e.isSet():
                return v
        else:
            e = Event()
            cache[key] = (None,e,time())
        #return NotReady
    finally:
        lock.release()
    e.wait(timeout)
    try:
        lock.acquire()
        if key in cache:
            (v,e,t) = cache[key]
            if e.isSet():
                return v
        else:
            return None
    finally:
        lock.release()
